home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / plnk081.zip / pilot-link.0.8.1 / libsock / padp.c < prev    next >
C/C++ Source or Header  |  1997-07-08  |  9KB  |  369 lines

  1. /* padp.c:  Pilot PADP protocol
  2.  *
  3.  * (c) 1996, D. Jeff Dionne.
  4.  * Much of this code adapted from Brian J. Swetland <swetland@uiuc.edu>
  5.  *
  6.  * Mostly rewritten by Kenneth Albanowski.
  7.  *
  8.  * This is free software, licensed under the GNU Public License V2.
  9.  * See the file COPYING for details.
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <errno.h>
  14. #include "pi-source.h"
  15. #include "pi-socket.h"
  16. #include "pi-padp.h"
  17. #include "pi-slp.h"
  18. #include "pi-serial.h"
  19.  
  20. #define xmitTimeout 4*10
  21. #define xmitRetries 14*10
  22.  
  23. /*@+matchanyintegral@*/
  24.  
  25. int padp_tx(struct pi_socket *ps, void *msg, int len, int type)
  26. /*@-predboolint@*/
  27. {
  28.   int flags = FIRST;
  29.   int tlen;
  30.   int count = 0;
  31.  
  32.   struct padp padp;
  33.  
  34.   struct pi_skb* nskb;
  35.   int retries;
  36.  
  37. #ifdef DEBUG
  38.   fprintf(stderr,"-----------------\n");
  39. #endif
  40.  
  41.   if (type == padWake) {
  42.     ps->xid = (unsigned char)0xff;
  43.   }
  44.  
  45.   if(ps->xid == (unsigned char)0)
  46.     ps->xid = (unsigned char)0x11; /* some random # */
  47.  
  48.   if(ps->initiator) {
  49.     if(ps->xid >= (unsigned char)0xfe)
  50.       ps->nextid = (unsigned char)1; /* wrap */
  51.     else
  52.       ps->nextid = ps->xid+(unsigned char)1;
  53.   } else {
  54.     ps->nextid = ps->xid;
  55.   }
  56.   
  57.   Begin(padp_tx);
  58.   
  59.   do {
  60.  
  61.     retries = xmitRetries;
  62.     do {
  63.  
  64.       nskb = (struct pi_skb *)malloc(sizeof(struct pi_skb));
  65.       
  66.       nskb->type = 2;
  67.       nskb->dest = nskb->source = PI_PilotSocketDLP;
  68.       nskb->id = ps->xid;
  69.  
  70.       tlen = (len > 1024) ? 1024 : len;
  71.  
  72.       memcpy(&nskb->data[14], msg, tlen);
  73.  
  74.       padp.type = type &0xff;
  75.       padp.flags = flags | (len == tlen ? LAST : 0);
  76.       padp.size = (flags ? len : count);
  77.  
  78.       set_byte((unsigned char*)(&nskb->data[10]), padp.type);
  79.       set_byte((unsigned char*)(&nskb->data[11]), padp.flags);
  80.       set_short((unsigned char*)(&nskb->data[12]), padp.size);
  81.  
  82.       padp_dump(nskb, &padp, 1);
  83.       
  84.       slp_tx(ps, nskb, tlen + 4);
  85.       
  86.       if (type == padTickle) /* Tickles don't get acks */
  87.         break;
  88.       
  89.       At("Reading Ack");
  90.       ps->serial_read(ps, xmitTimeout);
  91.  
  92.       if(ps->rxq) {
  93.         struct pi_skb *skb;
  94.         struct slp * slp;
  95.         skb = ps->rxq;
  96.  
  97.         slp = (struct slp*)skb->data;
  98.  
  99.         padp.type = get_byte((unsigned char*)(&skb->data[10]));
  100.         padp.flags = get_byte((unsigned char*)(&skb->data[11]));
  101.         padp.size = get_short((unsigned char*)(&skb->data[12]));
  102.  
  103.         padp_dump(skb, &padp, 0);
  104.  
  105.  
  106.         if ((slp->type == (unsigned char)2) && (padp.type == (unsigned char)padData) && 
  107.             (slp->id == ps->xid) && (len==0)) {
  108.           fprintf(stderr,"Missing ack\n");
  109.           /* Incoming padData from response to this transmission.
  110.              Maybe the Ack was lost */
  111.           /* Don't consume packet, and return success. */
  112.           return 0;
  113.         } 
  114.  
  115.         if ((slp->type == (unsigned char)2) && 
  116.             (padp.type == (unsigned char)padAck) && (slp->id == ps->xid)) {
  117.           /* Got correct Ack */
  118.           flags = (unsigned char)padp.flags;
  119.  
  120.           /* Consume packet */
  121.           ps->rxq = skb->next;
  122.           free(skb);
  123.               
  124.           if (flags & MEMERROR) {
  125.             fprintf(stderr,"Out of memory\n");
  126.             errno = EMSGSIZE;
  127.             return -1; /* Mimimum failure: transmission failed due to lack of
  128.                           memory in reciever link layer, but connection is still
  129.                           active. This transmission was lost, but other
  130.                           transmissions will be received. */
  131.           } else {
  132.             /* Successful Ack */
  133.             msg = ((char *)msg) + tlen;
  134.             len -= tlen;
  135.             count += tlen;
  136.             flags = 0;
  137.             break;
  138.           }
  139.         } else {
  140.           fprintf(stderr,"Weird packet\n");
  141.           /* Got unknown packet */
  142.           /* Don't consume packet */
  143.           errno = EIO;
  144.           return -1; /* Unknown failure: received unknown packet */
  145.         }
  146.       }
  147.     } while(--retries > 0);
  148.     
  149.     if( retries == 0) {
  150.       errno = ETIMEDOUT;
  151.       return -1; /* Maximum failure: transmission failed, and 
  152.                     the connection must be presumed dead */
  153.     }
  154.     
  155.   } while(len);
  156.   
  157.   if( type != padAck) 
  158.     ps->xid = ps->nextid;
  159.     
  160.   End(padp_tx);
  161.  
  162.   return count;
  163. }
  164.  
  165. #define recStartTimeout 45*10
  166. #define recSegTimeout 45*10
  167.  
  168.  
  169. int padp_rx(struct pi_socket *ps, void *buf, int len)
  170. {
  171.   struct pi_skb *skb;
  172.   struct padp padp;
  173.  
  174.   struct pi_skb *nskb;
  175.   struct padp npadp;
  176.  
  177.   struct slp * slp;
  178.   int data_len;
  179.   int offset = 0;
  180.   int ouroffset = 0;
  181.   time_t endtime;
  182.   endtime = time(NULL)+recStartTimeout;
  183.  
  184.   if(!ps->initiator) {
  185.     if(ps->xid >= 0xfe)
  186.       ps->nextid = 1; /* wrap */
  187.     else
  188.       ps->nextid = ps->xid+1;
  189.   } else {
  190.     ps->nextid = ps->xid;
  191.   }
  192.   
  193.   Begin(padp_rx);
  194.  
  195.   for(;;) {
  196.     if(time(NULL)>endtime) {
  197.       /* Start timeout, return error */
  198.       errno = ETIMEDOUT;
  199.       return -1;
  200.     }
  201.   
  202.     if (!ps->rxq) {
  203.       ps->serial_read(ps, recStartTimeout);
  204.       continue;
  205.     }
  206.  
  207.     skb = ps->rxq;
  208.     ps->rxq = skb->next;
  209.  
  210.     slp = (struct slp*)(skb->data);
  211.  
  212.     padp.type = get_byte((unsigned char*)(&skb->data[10]));
  213.     padp.flags = get_byte((unsigned char*)(&skb->data[11]));
  214.     padp.size = get_short((unsigned char*)(&skb->data[12]));
  215.     
  216.     if ((slp->type != 2) || (padp.type != padData) || 
  217.         (slp->id != ps->xid) || !(padp.flags & FIRST)) {
  218.       if(padp.type == padTickle) {
  219.         endtime = time(NULL)+recStartTimeout;
  220.         fprintf(stderr,"Got tickled\n");
  221.       }
  222.       fprintf(stderr,"Wrong packet type on queue\n");
  223.       free(skb);
  224.       ps->serial_read(ps, recStartTimeout);
  225.       continue;
  226.     }
  227.     break;
  228.   }
  229.   
  230.   /* OK, we got the expected begin-of-data packet */
  231.   
  232.   endtime = time(NULL) + recSegTimeout;
  233.   
  234.   for(;;) {
  235.   
  236.     At(got data);
  237.  
  238.     padp_dump(skb, &padp, 0);
  239.  
  240.     /* Ack the packet */
  241.     
  242.     nskb = (struct pi_skb *)malloc(sizeof(struct pi_skb));
  243.  
  244.     nskb->type = 2;
  245.     nskb->dest = nskb->source = PI_PilotSocketDLP;
  246.     nskb->id = ps->xid;
  247.  
  248.     npadp.type = padAck;
  249.     npadp.flags = padp.flags;
  250.     npadp.size = padp.size;
  251.  
  252.     set_byte((unsigned char*)(&nskb->data[10]), npadp.type);
  253.     set_byte((unsigned char*)(&nskb->data[11]), npadp.flags);
  254.     set_short((unsigned char*)(&nskb->data[12]), npadp.size);
  255.  
  256.     padp_dump(nskb, &npadp, 1);
  257.   
  258.     slp_tx(ps, nskb, 4);
  259.     pi_serial_flush(ps); /* It's an Ack, so flush it already */
  260.     At(sent Ack);
  261.     
  262.     /* calculate length and offset */
  263.     
  264.     offset = ((padp.flags & FIRST) ? 0 : padp.size);
  265.     data_len = get_short(&skb->data[6])-4;
  266.     
  267.     /* If packet was out of order, ignore it */
  268.     
  269.     if(offset == ouroffset) {
  270.       At(storing block);
  271.       memcpy((unsigned char*)buf + ouroffset, &skb->data[14], data_len);
  272.         
  273.       ouroffset += data_len;
  274.       free(skb);
  275.     }
  276.     
  277.     if (padp.flags & LAST) {
  278.       break;
  279.     } else  {
  280.       endtime = time(NULL) + recSegTimeout;
  281.       
  282.       for(;;) {
  283.         if(time(NULL)>endtime) {
  284.           fprintf(stderr,"segment timeout\n");
  285.           /* Segment timeout, return error */
  286.           errno = ETIMEDOUT;
  287.           return -1;
  288.         }
  289.         
  290.         if(!ps->rxq) {
  291.           ps->serial_read(ps, recSegTimeout);
  292.           continue;
  293.         }
  294.         
  295.         skb = ps->rxq;
  296.         ps->rxq = skb->next;
  297.       
  298.         slp = (struct slp*)(skb->data);
  299.  
  300.         padp.type = get_byte((unsigned char*)(&skb->data[10]));
  301.         padp.flags = get_byte((unsigned char*)(&skb->data[11]));
  302.         padp.size = get_short((unsigned char*)(&skb->data[12]));
  303.  
  304.         if ((slp->type != 2) || (padp.type != padData) || 
  305.             (slp->id != ps->xid) || (padp.flags & FIRST)) {
  306.           if(padp.type == padTickle) {
  307.             endtime = time(NULL)+recSegTimeout;
  308.             fprintf(stderr,"Got tickled\n");
  309.           }
  310.           fprintf(stderr,"Wrong packet type on queue\n");
  311.           free(skb);
  312.           ps->serial_read(ps, recSegTimeout);
  313.           continue;
  314.         }
  315.         At(got good packet);
  316.         break;
  317.       }
  318.     }
  319.   }
  320.  
  321.   ps->xid = ps->nextid;
  322.   
  323.   End(padp_rx);
  324.  
  325.   return ouroffset;
  326. }
  327.  
  328. void padp_dump(struct pi_skb *skb, struct padp* padp, int rxtx)
  329. {
  330. #ifdef DEBUG
  331.   int i;
  332.   int s;
  333.   char *stype;
  334.  
  335.   switch(padp->type) {
  336.   case padData:
  337.     stype = "DATA"; break;
  338.   case padAck:
  339.     stype = "ACK"; break;
  340.   case padTickle:
  341.     stype = "TICKLE"; break;
  342.   case padWake:
  343.     stype = "WAKE"; break;
  344.   case padAbort:
  345.     stype = "ABORT"; break;
  346.   default:
  347.     stype = "LOOP"; break;
  348.   }
  349.  
  350.   fprintf(stderr,"PADP %s %s %c%c%c len=0x%.4x\n",
  351.       stype,
  352.       rxtx ? "TX" : "RX" ,
  353.       (padp->flags & FIRST) ? 'F' : ' ',
  354.       (padp->flags & LAST) ? 'L' : ' ',
  355.           (padp->flags & MEMERROR) ? 'M' : ' ',
  356.       padp->size);
  357.  
  358.   s = padp->size;
  359.   if(s>1024) s=1024;
  360.   if (!(padp->type == padAck)) {
  361.     for (i=0; i < s; i += 16) {
  362.       dumpline(&skb->data[14 + i],
  363.            ((padp->size - i) < 16) ? padp->size - i : 16,
  364.            i);
  365.     }
  366.   }
  367. #endif
  368. }
  369.